﻿using MqLibrary;
using RabbitMqService.Workers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace RabbitMqService.Worker
{
    public class SendSMSWorker : IWorker
    {
        static SendSMSWorker()
        {
            IDictionary dict = ConfigurationManager.GetSection("SendSMS") as IDictionary;
            TEMPLATEMAILID = dict["TEMPLATEMAILID"].ToString();
            SMS_USER = dict["SMS_USER"].ToString();
            SMS_KEY = dict["SMS_KEY"].ToString();
            MSGTYPE = dict["MSGTYPE"].ToString();
            VARS = dict["VARS"].ToString();
        }
        //模板名称
        private static readonly string TEMPLATEMAILID;
        //用户标示
        private static readonly string SMS_USER;
        private static readonly string SMS_KEY;
        private static readonly string MSGTYPE;
        private static readonly string VARS;

        public void DoWork(Object o)
        {
            RabbitHelper<ShortMessageModel> cs = new RabbitHelper<ShortMessageModel>();
            JavaScriptSerializer js = new JavaScriptSerializer();
            bool RabbitIsNull = false;
          
            while (true)
            {
              
                if (RabbitIsNull)
                {
                    Thread.Sleep(5000);
                }
                ShortMessageModel result = cs.GetRabbitMq(RabbitTypeEnum.Message);
                if (result == null)
                {
                    RabbitIsNull = true;
                    continue;
                }

                Task<string> t = sendAsync(result);
                //发送失败的时候执行
                t.ContinueWith((task, r) =>
                {

                    if (task.Exception != null)
                    {
                        Log.WriteSMSlInfo("to" + r + "  发送失败  " + task.Exception.InnerException.Message);
                    }
                }, result.SendAddress, TaskContinuationOptions.OnlyOnFaulted);
                //发送成功的时候执行
                t.ContinueWith((task, r) =>
                {
                    var returnJson = js.Deserialize<ReturnJson>(task.Result);
                    //转发失败
                    if (returnJson != null && returnJson.Result == false)
                    {
                        Log.WriteSMSlInfo("to" + r + "  发送失败  " + returnJson.StatusCode + "  " + returnJson.Message);
                    }
                    else if (returnJson == null)
                    {
                        Log.WriteSMSlInfo("to" + r + "  发送失败   在json反序列化是出现问题");
                    }
                    //转发成功
                    else Log.WriteSMSlInfo("to" + r + "  发送成功");

                },
                result.SendAddress, TaskContinuationOptions.OnlyOnRanToCompletion);
                //发送取消是执行
                t.ContinueWith((task, r) =>
                {
                    Log.WriteSMSlInfo("to" + r + "  发送取消");
                }
                , result.SendAddress, TaskContinuationOptions.OnlyOnCanceled);
            }
        }

        public async Task<string> sendAsync(ShortMessageModel message)
        {

            String url = "http://www.sendcloud.net/smsapi/send";
            String smsUser = SMS_USER;
            String smsKey = SMS_KEY;
            String templateId = TEMPLATEMAILID;
            //测试的手机号码
            //String phone = "15502146926";
            String phone = message.SendAddress;
            String msgType = MSGTYPE;
            String var = VARS;
            var varsObject = new Vars { Code = message.MessageBody };
            JavaScriptSerializer js = new JavaScriptSerializer();
            var vars = js.Serialize(varsObject).Replace("Code", var);
            List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
            paramList.Add(new KeyValuePair<String, String>("smsUser", smsUser));
            paramList.Add(new KeyValuePair<String, String>("templateId", templateId));
            paramList.Add(new KeyValuePair<String, String>("phone", phone));
            paramList.Add(new KeyValuePair<String, String>("msgType", msgType));
            paramList.Add(new KeyValuePair<String, String>("vars", vars));

            paramList.Sort(
                delegate (KeyValuePair<String, String> p1, KeyValuePair<String, String> p2)
                {
                    return p1.Key.CompareTo(p2.Key);
                }
            );
            var param_str = "";
            foreach (var param in paramList)
            {
                param_str += param.Key.ToString() + "=" + param.Value.ToString() + "&";
            }
            String sign_str = smsKey + "&" + param_str + smsKey;
            String sign = generate_md5(sign_str);
            paramList.Add(new KeyValuePair<String, String>("signature", sign));
            HttpClient client = null;
            HttpResponseMessage response = null;
            try
            {
                client = new HttpClient();
                response = client.PostAsync(url, new FormUrlEncodedContent(paramList)).Result;
                return await response.Content.ReadAsStringAsync();
            }
            finally
            {
                if (null != response)
                {
                    response.Dispose();
                }
                if (null != client)
                {
                    client.Dispose();
                }
            }

        }


        public static String generate_md5(String str)
        {
            MD5 md5 = new MD5CryptoServiceProvider();

            //compute hash from the bytes of text
            md5.ComputeHash(Encoding.GetEncoding("utf-8").GetBytes(str));

            //get hash result after compute it
            byte[] result = md5.Hash;

            StringBuilder strBuilder = new StringBuilder();
            for (int i = 0; i < result.Length; i++)
            {
                strBuilder.Append(result[i].ToString("x2"));
            }

            return strBuilder.ToString();
        }

        public class Vars
        {
            public string Code { get; set; }
        }
    }
}
